package org.jsets.fastboot.frame.controller;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Serializable;
import java.util.Base64;
import java.util.List;
import java.util.Objects;
import javax.servlet.http.HttpServletResponse;
import org.jsets.fastboot.util.IoUtils;
import org.jsets.fastboot.util.StringUtils;
import org.springframework.util.FileCopyUtils;
import org.jsets.fastboot.model.BaseResp;
import org.jsets.fastboot.model.DataResp;
import org.jsets.fastboot.model.ListResp;
import com.baomidou.mybatisplus.core.metadata.IPage;

/**
 * Controller基类
 *
 * @author wangjie (https://github.com/wj596)
 * @date 2021.07.10 21:57
 * @since 0.1
 */
public abstract class BaseController {

	protected static final String RESP_INSERT_SUCCEED = "新增成功";
	protected static final String RESP_UPDATE_SUCCEED = "修改成功";
	protected static final String RESP_DELETE_SUCCEED = "删除成功";

	/**
	 * 操作成功
	 */
	protected BaseResp succeed() {
		return BaseResp.ok();
	}

	/**
	 * 操作成功
	 * 
	 * @param message 消息
	 */
	protected BaseResp succeed(String message) {
		return BaseResp.ok(message);
	}

	/**
	 * 操作失败
	 */
	protected BaseResp failed() {
		return BaseResp.fail();
	}

	/**
	 * 操作失败
	 * 
	 * @param message 响应消息
	 */
	protected BaseResp failed(String message) {
		return BaseResp.fail(message);
	}

	/**
	 * 返回单条数据
	 */
	protected <T> DataResp<T> dataResp(T t) {
		DataResp<T> respond = DataResp.ok();
		respond.setData(t);
		return respond;
	}

	/**
	 * 单条数据响应失败
	 */
	protected <T> DataResp<T> dataRespFail() {
		return DataResp.fail();
	}

	/**
	 * 单条数据响应失败
	 */
	protected <T> DataResp<T> dataRespFail(String message) {
		return DataResp.fail(message);
	}

	/**
	 * 返回数据列表
	 */
	protected <T> ListResp<T> listResp(List<T> ls) {
		ListResp<T> resp =  ListResp.ok();
		resp.setData(ls);
		return resp;
	}

	/**
	 * 数据列表响应失败
	 */
	protected <T> ListResp<T> listRespFail() {
		return ListResp.fail();
	}

	/**
	 * 数据列表响应失败
	 */
	protected <T> ListResp<T> listRespFail(String message) {
		return ListResp.fail(message);
	}

	/**
	 * 返回分页数据
	 */
	protected <T> ListResp<T> pageResp(IPage<T> result) {
		ListResp<T> respond = ListResp.ok();
		respond.setData(result.getRecords());
		respond.setTotalCount(result.getTotal());
		return respond;
	}

	/**
	 * 分页数据响应失败
	 */
	protected <T> ListResp<T> pageResp() {
		return this.listRespFail();
	}

	/**
	 * 分页数据响应失败
	 */
	protected <T> ListResp<T> pageResp(String message) {
		return this.listRespFail(message);
	}

	/**
	 * 参数断言
	 * 
	 * @param expression 表达式
	 * @param message    异常消息
	 */
	protected void assertArgumentThat(final boolean expression, final String message) {
		if (!expression) {
			throw new IllegalArgumentException(message);
		}
	}

	/**
	 * 参数断言
	 * 
	 * @param expression 表达式
	 * @param formatter  消息格式
	 * @param args       消息参数
	 */
	protected void assertArgumentThat(final boolean expression, final String formatter, final Object... args) {
		if (!expression) {
			throw new IllegalArgumentException(String.format(formatter, args));
		}
	}

	/**
	 * 断言参数不为空
	 * 
	 * @param argument     参数
	 * @param argumentName 参数名称
	 */
	protected void assertArgumentNotNull(final Object argument, final String argumentName) {
		if (Objects.isNull(argument)) {
			throw new IllegalArgumentException("参数[" + argumentName + "],不能为空");
		}
	}

	/**
	 * 断言参数不为空字符串
	 * 
	 * @param argument     参数
	 * @param argumentName 参数名称
	 */
	protected void assertArgumentNotEmpty(final String argument, final String argumentName) {
		if (StringUtils.isEmpty(argument)) {
			throw new IllegalArgumentException("参数[" + argumentName + "],不能为空");
		}
	}

	/**
	 * 断言参数不为空白字符串
	 * 
	 * @param argument     参数
	 * @param argumentName 参数名称
	 */
	protected void assertArgumentNotBlank(final String argument, final String argumentName) {
		if (StringUtils.isBlank(argument)) {
			throw new IllegalArgumentException("参数[" + argumentName + "],不能为空或空白字符串");
		}
	}
	
	/**
	 * 断言实体不为空
	 * 
	 * @param entity 实体
	 * @param id 主键
	 */
	protected void assertEntityNotNull(final Object entity, final Serializable id) {
		if (Objects.isNull(entity)) {
			throw new IllegalArgumentException("找不到主键为[" + id + "]的实体");
		}
	}

	protected void assertThat(final boolean expression, final RuntimeException exception) {
		if (!expression) {
			throw exception;
		}
	}
	
	protected void writeToResponse(final HttpServletResponse response, final InputStream inputStream, final String fileName) {
		response.setHeader("content-type", "application/octet-stream");
		response.setContentType("application/octet-stream");
		try {
			response.setHeader("Content-Disposition","attachment;filename=" + new String(fileName.getBytes("UTF-8"), "ISO-8859-1"));
			OutputStream output = response.getOutputStream();
			FileCopyUtils.copy(inputStream, output);
			output.flush();
		} catch (IOException e) {
			throw new RuntimeException(e.getMessage(), e);
		} finally {
			IoUtils.closeQuietly(inputStream);
		}
	}
	
	protected void writeToResponse(final HttpServletResponse response, final InputStream inputStream) {
		response.setHeader("content-type", "application/octet-stream");
		response.setContentType("application/octet-stream");
		try {
			response.setHeader("Content-Disposition","attachment;filename=" + new String(StringUtils.getUUID().getBytes("UTF-8"), "ISO-8859-1"));
			OutputStream output = response.getOutputStream();
			FileCopyUtils.copy(inputStream, output);
			output.flush();
		} catch (IOException e) {
			throw new RuntimeException(e.getMessage(), e);
		} finally {
			IoUtils.closeQuietly(inputStream);
		}
	}
	
	protected String toBase64(final InputStream inputStream) {
		try {
            byte[] arr = new byte[inputStream.available()];
            inputStream.read(arr);
            String str = Base64.getEncoder().encodeToString(arr);
            return str;
		} catch (IOException e) {
			throw new RuntimeException(e.getMessage(), e);
		} finally {
			IoUtils.closeQuietly(inputStream);
		}
	}
}